package cn.xyfmzmy.decorator.input;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 每次都先读一部分到缓冲区，然后直接从缓冲区里读；
 * 而不是每次读一个字节；
 * IO的体系是装饰器模式
 */
public class BufferedFileInputStream extends InputStream {

    private final byte[] buffer = new byte[8192];       // 缓冲区
    private int position = -1;                          // 读取的位置
    private int capacity = -1;                          // 每次读取的容量,而不是每次都读满8192
    private final FileInputStream fileInputStream;      // 装饰器代理的原对象

    public BufferedFileInputStream(FileInputStream fileInputStream) {
        this.fileInputStream = fileInputStream;
    }

    @Override
    public int read() throws IOException {
        if(bufferCanRead()){
            return readFromBuffer();
        }
        refreshBuffer();
        if(!bufferCanRead()){
            return -1;
        }
        return readFromBuffer();
    }

    private void refreshBuffer() throws IOException {
        capacity = fileInputStream.read(buffer);
        position = 0;
    }

    private int readFromBuffer() {
        return buffer[position++] & 0xff;   // 要求返回0~255,& 0xff 去符号
    }

    private boolean bufferCanRead() {
        if(capacity == -1){
            return false;
        }
        if(position == capacity){
            return false;
        }
        return true;
    }

    @Override
    public void close() throws IOException {
        fileInputStream.close();
    }
}
